import { ref, onMounted, reactive, toRefs } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import defaultApi from './api'

export default function useTable(
  // 注：传入的api 为接口地址形式 则默认用defaultApi中的请求方法；如果为一个对象（src/api文件中暴露出来的对象） 则会直接使用api方法调用
  // 如：将import * as API from '@/api/menu' 的API传入，就是直接调用当前传入的API方法
  api, // 获取表格相关数据 接口地址 或者 api 方法 增删改查
  isPageable = true, // 是否有分页
  isInit = true, // 是否初始化调用获取列表接口
) {
  // 判断当前传入的api是字符串地址 还是 对象
  let API = Object.prototype.toString.call(api) === '[object String]' ? defaultApi(api) : api

  // data------
  let dataSource = reactive({
    list: [],
    total: 0,
  })
  // 分页请求参数
  let pages = reactive({
    pageIndex: 1,
    pageSize: 10,
  })

  let loading = ref(false)
  let delLoading = ref(false)
  let addLoading = ref(false)
  let updateLoading = ref(false)
  let parameters = ref({})

  //------------------

  onMounted(() => {
    if (API === '' || API == null) {
      return
    }
    isInit && initPage()
  })

  // function------
  // 初始化
  const initPage = () => {
    pages.pageIndex = 1
    pages.pageSize = 10
    getList()
  }
  // 分页 / 全量 获取list 不传pages则查全量
  const getList = async (params = {}) => {
    // 在获取列表的时候将其他参数存起来 方便其他条件改变时重新带参数获取列表
    parameters.value = JSON.parse(JSON.stringify(params))

    loading.value = true
    try {
      //合并查询参数
      let allParams = Object.assign({}, isPageable ? pages : {}, parameters.value)
      let res = await API.getListApi({
        params: allParams,
      })
      loading.value = false
      dataSource.list = res?.items ?? []
      dataSource.total = res?.totalCount > 0 ? res?.totalCount : 0
      pages.pageIndex = res?.pageIndex || pages.pageIndex
      pages.pageSize = res?.pageSize || pages.pageSize
      return res
    } catch (error) {
      loading.value = false
      dataSource.list = []
      dataSource.total = 0
      return null
    }
  }

  // 设置跳转到哪一页，即设置当前页数 并获取列表
  const setPageIndex = index => {
    pages.pageIndex = index
    getList(parameters.value)
  }

  //设置每页数目 重新从第一页获取列表
  const setPageSize = size => {
    pages.pageSize = size
    pages.pageIndex = 1
    getList(parameters.value)
  }

  // 添加 data: 请求body中的其他参数
  const addFun = async (data = {}) => {
    addLoading.value = true
    try {
      let res = await API.addApi({
        data,
      })
      addLoading.value = false
      ElMessage({
        message: '新增成功！',
        type: 'success',
        duration: 1000,
      })
      getList(parameters.value)
      return res
    } catch (error) {
      addLoading.value = false
      return null
    }
  }

  // 更新/修改编辑 id: 当前修改数据的id data: 请求body中的其他参数
  const updateFun = async (id, data = {}) => {
    updateLoading.value = true
    try {
      let res = await API.updateApi(id, {
        data,
      })
      updateLoading.value = false
      ElMessage({
        message: '修改成功！',
        type: 'success',
        duration: 1000,
      })
      getList(parameters.value)
      return res
    } catch (error) {
      updateLoading.value = false
      return null
    }
  }

  // 修改当前行的状态（用户和角色有） options{id: 当前修改数据的id ，state: 修改的状态}
  const editStateFun = async (options = {}) => {
    updateLoading.value = true
    try {
      let res = await API.editStateApi(options)
      updateLoading.value = false
      ElMessage({
        message: '修改成功！',
        type: 'success',
        duration: 1000,
      })
      getList(parameters.value)
      return res
    } catch (error) {
      updateLoading.value = false
      return null
    }
  }

  // 删除 params: 请求params中的其他参数
  const deleteFun = async data => {
    try {
      delLoading.value = true
      ElMessageBox.confirm(`是否删除?`, '提示', {
        confirmButtonText: '确 定',
        cancelButtonText: '取 消',
        type: 'warning',
      })
        .then(async () => {
          let res = await API.deleteApi({
            data,
          })
          ElMessage({
            message: '删除成功！',
            type: 'success',
            duration: 1000,
          })
          getList(parameters.value)
          delLoading.value = false
          return res
        })
        .catch(() => {})
    } catch (error) {
      delLoading.value = false
    }
  }

  const { list, total } = toRefs(dataSource)

  return {
    list,
    total,
    ...toRefs(pages),
    currentPage: pages.pageIndex,
    loading,
    addLoading,
    updateLoading,
    delLoading,
    setPageIndex,
    setPageSize,
    getList,
    addFun,
    updateFun,
    deleteFun,
    editStateFun,
    initPage,
    refreshPage: () => getList,
  }
}
